/* 
 * Copyright (C) 2007 - 2010 Amerika Labs <http://amerika-labs.com/>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 
 */

#include <string>
#include "Chat.h"
#include "Player.h"
#include "Mail.h"
#include "Common.h"
#include "ObjectMgr.h"
#include "Log.h"
#include "AccountMgr.h"
#include "Guild.h"

#include "ScriptedCreature.h"

bool ChatHandler::HandleMailSendCommand(const char* args)
{
	if (!*args)
		return false;

	sLog.outError("Args: %s", args);
	int lsize = strlen(args);

	char *recp = strtok((char*)args, " ");
		sLog.outError("Args: Recp: %s", recp);
		int strsize = strlen(recp);
	char *sndr = strtok(NULL, " ");
		sLog.outError("Args: Sndr: %s", sndr);
		strsize = strsize + strlen(sndr);
		strsize = strsize + 2;
		sLog.outError("Args: %s", args+strsize);
	char *tail1 = (char*)args+strsize;
		sLog.outError("Arg: tail1: %s", tail1);
	char *tail2 = strstr(tail1, "\" \"");
	tail2 = (char*)tail2+2;
		sLog.outError("Arg: tail2: %s", tail2);
	
	sLog.outError("Savestr: %s", tail1);
	
	if (!recp || !sndr)
	{
		sLog.outError("Player %s attempted to send mail to %s", sndr, recp);
		return false;
	}

	/* Recipient */
	Player* target;
	uint64 target_guid;
	std::string target_name;
	
	/* Sender */
	Player* sender;
	uint64 sender_guid;
	std::string sender_name;
	
	/* Get Recipient data */
	if (!extractPlayerTarget(recp,&target,&target_guid,&target_name))
	{
		sLog.outError("Could not extract player %s", args);
		return false;
	}
	
	/* Get Sender data */
	if (!extractPlayerTarget(sndr,&sender,&sender_guid,&sender_name))
	{
		sLog.outError("Could not extract player %s", args);
		return false;
	}

	char* msgSubject = extractQuotedArg(tail1);
	if (!msgSubject)
	{
		sLog.outError("Could not extract subject text from quotes: %s", msgSubject);
		return false;
	}

	char* msgText = extractQuotedArg(tail2);
	if (!msgText)
	{
		sLog.outError("Could not extract body text from quotes: %s", msgText);
		return false;
	}

	/* msgSubject and msgText are not NULL after previous check */
	std::string subject = msgSubject;
	std::string text = msgText;

	/* Make sending player into the correct datatype */
	MailSender MSsender(MAIL_NORMAL, sender_guid, MAIL_STATIONERY_DEFAULT);

	MailDraft(subject, text)
		.SendMailTo(MailReceiver(target,GUID_LOPART(target_guid)), MSsender);

	std::string nameLink = playerLink(target_name);
	PSendSysMessage(LANG_MAIL_SENT, nameLink.c_str());
	return true;
}

bool ChatHandler::HandleCreateTicketCommand(const char* args)
{
	if (!*args)
		return false;

	uint32 map = 0;
	float x, y, z;
	std::string ticketText;

	Player *pPlayer;
	uint64 plrGUID;
	std::string plr_name;

	char* player = strtok((char*)args, " ");
	int plrSize = strlen(player);
	plrSize += 1;	
	char* tictxt = (char*)args+plrSize;

	if (!extractPlayerTarget(player, &pPlayer, &plrGUID, &plr_name))
	{
		sLog.outError("Could not extract player: %s", args);
		return false;
	}

	char* tikTxt = extractQuotedArg(tictxt);
	if (!tikTxt)
	{
		sLog.outError("Could not extract ticket text: %s", tikTxt);
		return false;
	}

	ticketText = tikTxt;

	float plrX = 0;
	float plrY = 0;
	float plrZ = 0;
	

	GM_Ticket *ticket = new GM_Ticket;
	ticket->name = plr_name;
	ticket->guid = sObjectMgr.GenerateGMTicketId();
	ticket->playerGuid = plrGUID;
	ticket->message = ticketText;
	ticket->createtime = time(NULL);
	ticket->map = map;
	ticket->pos_x = plrX;
	ticket->pos_y = plrY;
	ticket->pos_z = plrZ;
	ticket->timestamp = time(NULL);
	ticket->closed = 0;
	ticket->assignedToGM = 0;
	ticket->comment = "";

	sObjectMgr.AddOrUpdateGMTicket(*ticket, true);

//	sWorld.SendGMText(LANG_COMMAND_TICKETUPDATED, plr_name, ticket->guid);

	return true;
}

bool ChatHandler::HandleAmerikaTicketClose(const char* args)
{
	if (!*args)
		return false;

	char *tok1 = strtok((char*)args, " ");	// ticket guid
	char *tok2 = strtok(NULL, " ");		// player name

	uint64 tguid = atoi(tok1);
	GM_Ticket *ticket = sObjectMgr.GetGMTicket(tguid);
	if (!ticket || ticket->closed != 0)
	{
		SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
		return true;
	}

	Player* target;
	uint64 target_guid;
	std::string target_name;
	if (!extractPlayerTarget(tok2, &target, &target_guid, &target_name))
	{
		sLog.outError("Could not extract player %s", args);
		return false;
	}

	if (ticket && ticket->assignedToGM != 0 && ticket->assignedToGM != target_guid)
	{
		PSendSysMessage(LANG_COMMAND_TICKETCANNOTCLOSE, ticket->guid);
		return true;
	}

	std::stringstream ss;
	ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
	ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
	ss << PGetParseString(LANG_COMMAND_TICKETCLOSED, target_name.c_str());
	SendGlobalGMSysMessage(ss.str().c_str());
	Player *plr = sObjectMgr.GetPlayer(ticket->playerGuid);
	sObjectMgr.RemoveGMTicket(ticket, target_guid);

	WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
	data << uint32(9);
	return true;
}

bool ChatHandler::HandleAmerikaAssignTicket(const char* args)
{
	if (!*args)
		return false;

	char* tguid = strtok((char*)args, " ");
	uint64 ticketGuid = atoi(tguid);
	char* gmplr = strtok(NULL, " ");

	if (!gmplr)
		return false;

	Player* target;
	uint64 target_guid;
	std::string target_name;

	if (!extractPlayerTarget(gmplr, &target, &target_guid, &target_name))
	{
		sLog.outError("Could not extract player %s", args);
		return false;
	}

	GM_Ticket *ticket = sObjectMgr.GetGMTicket(ticketGuid);

	if (!ticket || ticket->closed != 0)
	{
		SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
		return true;
	}

	uint64 accountid = sObjectMgr.GetPlayerAccountIdByGUID(target_guid);
	uint32 gmlevel = sAccountMgr.GetSecurity(accountid, realmID);

	if (!target_guid || gmlevel == SEC_PLAYER)
	{
		SendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_A);
		return true;
	}

	if (ticket->assignedToGM == target_guid)
	{
		PSendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_B, ticket->guid);
		return true;
	}

	if (ticket->assignedToGM != 0 && ticket->assignedToGM != target_guid)
	{
		PSendSysMessage(LANG_COMMAND_TICKETALREADYASSIGNED, ticket->guid, target_name.c_str());
		return true;
	}

	ticket->assignedToGM = target_guid;
	sObjectMgr.AddOrUpdateGMTicket(*ticket);
	std::stringstream ss;
	ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
	ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
	ss << PGetParseString(LANG_COMMAND_TICKETLISTASSIGNEDTO, target_name.c_str());
	SendGlobalGMSysMessage(ss.str().c_str());
	return true;
}

bool ChatHandler::HandleAmerikaDeleteTicket(const char* args)
{
	if (!*args)
		return false;

	char* tok1 = strtok((char*)args, " ");
	uint64 ticketGuid = atoi(tok1);
	char* plrname = strtok(NULL, " ");

	Player* target;
	uint64 target_guid;
	std::string target_name;

	if (!extractPlayerTarget(plrname, &target, &target_guid, &target_name))
	{
		sLog.outError("Could not extract player %s", plrname);
		return false;
	}

	GM_Ticket *ticket = sObjectMgr.GetGMTicket(ticketGuid);

	if (!ticket)
	{
		SendSysMessage(LANG_COMMAND_TICKETNOTEXIST);
		return true;
	}

	if (ticket->closed == 0)
	{
		SendSysMessage(LANG_COMMAND_TICKETCLOSEFIRST);
		return true;
	}

	std::stringstream ss;
	ss << PGetParseString(LANG_COMMAND_TICKETLISTGUID, ticket->guid);
	ss << PGetParseString(LANG_COMMAND_TICKETLISTNAME, ticket->name.c_str());
	ss << PGetParseString(LANG_COMMAND_TICKETDELETED, target_name.c_str());
	
	SendGlobalGMSysMessage(ss.str().c_str());
	Player *plr = sObjectMgr.GetPlayer(ticket->playerGuid);
	sObjectMgr.RemoveGMTicket(ticket, -1, true);
	if (plr && plr->IsInWorld())
	{
		WorldPacket data(SMSG_GMTICKET_DELETETICKET, 4);
		data << uint32(9);
		plr->GetSession()->SendPacket(&data);
	}

	ticket = NULL;
	return true;
}

bool ChatHandler::HandleUpdateGuildMOTD(const char* args)
{
	if (!*args)
		return false;

	char* player = strtok((char*)args, " ");
	int strsze = strlen(player);
	strsze += 1;
	char* motd = (char*)args+strsze;

	Player *target;
	uint64 target_guid;
	std::string target_name;

	if (!extractPlayerTarget(player, &target, &target_guid, &target_name))
	{
		sLog.outError("Could not extract player target: %s", args);
		return false;
	}

	char* tmotd = extractQuotedArg(motd);
	if (!tmotd)
	{
		sLog.outError("Could not extract MOTD text");
		return false;
	}

	std::string motdtext = tmotd;

	uint32 guildID = target->GetGuildIdFromDB(target_guid);
	if (!guildID)
	{
		sLog.outError("Could not get Guild ID from Player: %s", target_name);
		return false;
	}

	Guild *guild = sObjectMgr.GetGuildById(guildID);
	if (!guild)
	{
		sLog.outError("Player %s not in guild.", target_name);
		return false;
	}

	if (!guild->HasRankRight(target->GetRankFromDB(target_guid), GR_RIGHT_SETMOTD))
	{
		sLog.outError("Player %s does not have permission to set guild MOTD", target_name);
		return false;
	}

	guild->SetMOTD(motdtext);

	WorldPacket data(SMSG_GUILD_EVENT, (2+motdtext.size()+1));
	data << (uint8)GE_MOTD;
	data << (uint8)1;
	data << motdtext;
	guild->BroadcastPacket(&data);

	sLog.outDebug("WORLD: Sent (SMSG_GUILD_EVENT)");
	return true;
}
